/*
 * JSCurve.js
 * Barreto-Naehrig (BN) pairing-friendly elliptic curves.
 * Copyright (C) Jorge H. C. Lucema.
 */

function JSCurve(bn) {
    if (bn instanceof JSParams) {
        this._1 = new BigInteger("1");
        this._2 = new BigInteger("2");
        this._3 = new BigInteger("3");
        this.reducer = new Barrett(bn.p);
        this.bn = bn;
        this.b = (bn.b === 3) ? this._3 : this._2;
        this.infinity = new JSPoint(this); // caveat: must be set *after* p but *before* G!
        this.G = (bn.b === 3) ? new JSPoint(this, this._1, this._2) : new JSPoint(this, this._1.negate(), this._1);
    }
}

/*
 * Get a random nonzero point on this curve, given a fixed base point
 * @param {SecureRandom} rand
 * @returns a random nonzero point on this curve
 */

function pointFactory(rand) {
    if (rand instanceof SecureRandom) {
        do {
            var x = new BigInteger(2*this.bn.p.bitLength(), rand).mod(this.bn.p);
            var y = this.bn.sqrt(x.multiply(x).multiply(x).add(this.b));
        } while (y === null);
        return new JSPoint(this, x, y);
    } else {
        throw new Error("Parameter is not a cryptographically strong PRNG");
    }
}

function curveReduce(x) {
    this.reducer.reduce(x);
}

JSCurve.prototype.pointFactory = pointFactory;
JSCurve.prototype.reduce = curveReduce;